package NextClass.Native;

import NextClass.NativeClass;
import NextClass.NextClassAPI;
import app.boot.BaseFunction;
import app.boot.Main;
import build.Bin.Function;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;

import vm.runtime.NextVMRuntime;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;


class HttpRun implements HttpHandler , Serializable {

    private String extraData = null;
    private NextVMRuntime nextVMRuntime = null;

    /**
     * 将HttpExchange中的请求头转换为字符串。
     *
     * @param exchange HttpExchange对象，从中获取请求头
     * @return 包含所有请求头的字符串
     */
    public static String getHeadersAsString(HttpExchange exchange) throws IOException {
        Map<String, List<String>> headers = exchange.getRequestHeaders();
        StringBuilder headersString = new StringBuilder();

        for (Map.Entry<String, List<String>> header : headers.entrySet()) {
            headersString.append(header.getKey()).append(": ");
            for (String value : header.getValue()) {
                headersString.append(value).append(", ");
            }
            // Remove the last comma and space
            headersString.setLength(headersString.length() - 2);
            headersString.append("\n");
        }

        return headersString.toString();
    }

    /**
     * 获取 Http氢气的主要消息体
     */
    public static byte[] getBodyAsByteArray(HttpExchange exchange) throws IOException {
        InputStream is = exchange.getRequestBody();
        ReadableByteChannel channel = Channels.newChannel(is);
        ByteBuffer buffer = ByteBuffer.allocate(1024); // 可以调整缓冲区大小
        int bytesRead;
        int totalBytesRead = 0;

        // 循环读取直到没有更多数据
        while ((bytesRead = channel.read(buffer)) != -1) {
            totalBytesRead += bytesRead;
            buffer.clear(); // 清除缓冲区，准备下一次读取
        }
        return buffer.array();
    }

    public HttpRun(NextVMRuntime nextVMRuntime,String extraData) {
        this.extraData = extraData;
        this.nextVMRuntime = nextVMRuntime;
    }


    public void triggerSystemGCWithProbability() {
        // 生成一个0.0到1.0之间的随机数
        double randomValue = Math.random();

        // 如果随机数小于0.001（即1000分之一的概率），则触发垃圾回收
        if (randomValue < 0.001) {
            System.gc();
        }
    }

    private void clearNativeClass(NativeClass nativeClass) {
        if (nativeClass != null) {
            nativeClass.ClassName = null;
            nativeClass.Methods = null;
            nativeClass.InitObject = null;
        }
    }

    private void clearFunction(NextVMRuntime fn) {
        if (fn != null) {
            fn.values.clear();
            fn = null;
        }
    }

    @Override
    public void handle(HttpExchange httpExchange) throws IOException{
        String pointer_1 = null;
        NextVMRuntime fn = null;
        try {
            System.out.println("["+httpExchange.getRemoteAddress().getAddress().toString()+"] "+httpExchange.getRequestURI().toString());
            pointer_1 = String.valueOf(BaseFunction.getRandomLong());
            NativeClass nativeClass = (NativeClass) NextClassAPI.nativeClassHashMap.get("Res").clone();

            nativeClass.Init("Res", httpExchange);
            nextVMRuntime.values.put(pointer_1, nativeClass);

            fn = NextVMRuntime.getFunctionFromRuntime(extraData, nextVMRuntime);
            assert fn != null;
            fn.values.clear();
            fn.Functions.clear();
            fn.LastRuntime = nextVMRuntime;
            fn.AllowRun = true;
            fn.IsInRootFunction = true;
            Function.putInputFunction(extraData, fn, nextVMRuntime, new String[]{pointer_1}); // 直接传递pointer_1

            fn.run();
            httpExchange.close();
            // 由于nativeClass可能还被其他地方引用，确保这里清除它的状态，以减少内存占用
            clearNativeClass(nativeClass);

        } catch (Exception e) {
            //e.printStackTrace();
            httpExchange.sendResponseHeaders(500, 0);
        } finally {
            // 确保在finally块中释放资源
            nextVMRuntime.values.remove(pointer_1);
            httpExchange.close();
            clearFunction(fn); // 假设有一个clearFunction方法来清理fn对象
            //triggerSystemGCWithProbability();
        }
    }
}

public class HttpService implements Serializable {
    public static String[] ClassMethods = {
            "URL",
            "start",
            "thread"
    };
    public static Object run(String Invoke, Object object,NextVMRuntime nextVMRuntime, Object... objects) throws Exception{
        HttpServer httpServer = (HttpServer) object;

        if (Invoke.equals("URL")) {
            String URL = (String) objects[0];
            String FuncName = null;
            if (objects[1] instanceof NextVMRuntime) {
                FuncName = ((NextVMRuntime) objects[1]).RuntimeName;
            } else {
                FuncName = (String) objects[1];
            }

            httpServer.createContext(URL , new HttpRun(nextVMRuntime,FuncName));
            return null;
        }
        else if (Invoke.equals("thread")) {
            int thread = Integer.parseInt(String.valueOf(objects[0]));
            httpServer.setExecutor(Executors.newFixedThreadPool(thread));
            return null;
        }
        else if (Invoke.equals("start")) {
            System.out.println("[INFO] Start HttpService: "+httpServer.getAddress().getHostName()+":"+httpServer.getAddress().getPort()+"");
            System.out.println("[INFO] Start System.gc() .");
            httpServer.start();
            Main.JavaGC_Thread();
            return null;
        }
        else if (Invoke.equals("cors")) {
            return "Access-control-allow-headers: *\n" +
                    "Access-control-allow-methods: POST\n" +
                    "Access-control-allow-origin: *";
        }
        else {
            return null;
        }
    }
}
